#!/usr/bin/python
import sys
from scapy import *
from scapy.all import *
from datetime import datetime
import uuid
import argparse

# Constantes
ECHO_REPLY = 0
DESTINATION_UNREACHABLE = 3
TIME_EXCEEDED = 11

#Se ejecuta 500 mediciones por TTL, y se planean ejecutar varias ejecuciones el programa para promediar los TTLs promediados 

def traceroute (dst, ttl = 1, nPacketsPerTtl = 500, timeout = 1):
	identificadorCorrida = str(uuid.uuid1())
	reached = 0
	for ttl_i in range(1,ttl+1):
		# armamos el paquete ICMP
		pck = IP(dst = dst, ttl = ttl_i) / ICMP()
				
		for pckCount in range(nPacketsPerTtl):
			timeStart = datetime.now()
			response = sr1(pck, timeout = timeout)  #sr1 devuelve el paquete (o conjunto de paquetes) respuesta al mensaje enviado
			timeEnd = datetime.now()
			rtt = (timeEnd - timeStart).microseconds * 1000 #milisegundos
			
			if len(response) > 0:
				if response[0].payload.type == TIME_EXCEEDED or response.payload.type == ECHO_REPLY:
					hop = response.payload.src
				if response.payload.type == ECHO_REPLY:
					reached = 1
				print identificadorCorrida + ';ttl:' + str(ttl_i) + ';pck:' + str(pckCount) + ';hop:' + str(hop) + ';rtt:' + str(rtt)	
			else 
				print identificadorCorrida + ';ttl:' + str(ttl_i) + ';pck:' + str(pckCount) + ';hop:' + str(hop) + ';rtt: - ' 	
		# fin for pckCount
		
		# si llegamos al destino, cortamos
		if reached:
			break;
	#fin for ttl_i	
	
# Punto de entrada del script. 
if __name__ == '__main__':
	
	#Obtener direccionURL
	try:
		direccionURL = sys.argv[1]
	except:
		print 'Uso: traceroutePropio direccionnURL [nVecesPromedio]'
		exit()

	parser = argparse.ArgumentParser(description='Trabajo practico de Teoria de las Comunicaciones\n UBA - DC - 2013C2')
	parser.add_argument('-url', '-URL', help='URL', required=True)
	parser.add_argument('-ttl', '-TTL', help='TTL (default = 20)', required=False, default=20)
	parser.add_argument('-n','--nPerTTL',help='Numero de paquetes icmp a enviar por ttl (default = 1)', required=False, default=1)
	parser.add_argument('-t','--Timeout',help='Timeout (default = 1)', required=False, default=1)
	args = parser.parse_args()
	traceroute(args.url, int(args.ttl), int(args.nPerTTL), int(args.timeout))
	